// /src/app/utils/resource.monitor.js
'use strict';

const os = require('os');
const diskusage = require('diskusage'); // 需安装：npm install diskusage
const { logger, color, emailTool } = require('./logger.utils');
const config = require('../config');

const ALERT_EMAILS = config.environment.alert.receiveEmails.split(',');
const MEMORY_THRESHOLD = config.environment.alert.memoryThreshold;
const DISK_THRESHOLD = config.environment.alert.diskThreshold;
const NODE_ENV = config.environment.nodeEnv;
let monitorInterval = null;

// 计算内存使用率
const getMemoryUsage = () => {
    const totalMem = os.totalmem();
    const freeMem = os.freemem();
    const usedMem = totalMem - freeMem;
    const usagePercent = Math.round((usedMem / totalMem) * 100);
    return {
        totalMem: (totalMem / 1024 / 1024 / 1024).toFixed(2) + 'GB',
        usedMem: (usedMem / 1024 / 1024 / 1024).toFixed(2) + 'GB',
        freeMem: (freeMem / 1024 / 1024 / 1024).toFixed(2) + 'GB',
        usagePercent,
    };
};

// 计算磁盘使用率
const getDiskUsage = async () => {
    try {
        const path = os.platform() === 'win32' ? 'C:' : '/';
        const { total, free } = await diskusage.check(path);
        const used = total - free;
        const usagePercent = Math.round((used / total) * 100);
        return {
            path,
            total: (total / 1024 / 1024 / 1024).toFixed(2) + 'GB',
            used: (used / 1024 / 1024 / 1024).toFixed(2) + 'GB',
            free: (free / 1024 / 1024 / 1024).toFixed(2) + 'GB',
            usagePercent,
        };
    } catch (err) {
        logger.error(`${color.red}❌ 磁盘使用率获取失败：${err.message}${color.reset}`, { metadata: {} });
        return null;
    }
};

// 资源监控启动函数
const start = () => {
    if (NODE_ENV !== 'production' || monitorInterval) return;

    // 每5分钟检查一次（企业级推荐：避免频繁告警）
    monitorInterval = setInterval(
        async () => {
            const memory = getMemoryUsage();
            const disk = await getDiskUsage();

            logger.debug(
                `📊  资源监控：内存使用率=${memory.usagePercent}% | 磁盘使用率=${disk ? disk.usagePercent : '未知'}%`,
                { metadata: {} },
            );

            // 内存超限告警
            if (memory.usagePercent >= MEMORY_THRESHOLD) {
                const alertContent = `
                <p>🚨 [预警] CorpHR系统内存使用率超限</p>
                <p>时间：${new Date().toLocaleString()}</p>
                <p>环境：${NODE_ENV}</p>
                <p>总内存：${memory.totalMem}</p>
                <p>已用内存：${memory.usedMem}</p>
                <p>空闲内存：${memory.freeMem}</p>
                <p>使用率：${memory.usagePercent}%（阈值：${MEMORY_THRESHOLD}%）</p>
                <p>风险：内存不足可能导致服务卡顿、崩溃</p>
                <p>解决方案：</p>
                <p>1. 检查是否存在内存泄漏</p>
                <p>2. 重启服务释放内存</p>
                <p>3. 升级服务器内存配置</p>
            `;
                ALERT_EMAILS.forEach((email) => {
                    emailTool
                        .sendNotice(email, '[预警] CorpHR内存使用率超限告警', alertContent)
                        .catch((mailErr) =>
                            logger.error(`❌ 内存告警邮件发送失败：${mailErr.message}`, { metadata: {} }),
                        );
                });
            }

            // 磁盘超限告警
            if (disk && disk.usagePercent >= DISK_THRESHOLD) {
                const alertContent = `
                <p>🚨 [预警] CorpHR系统磁盘使用率超限</p>
                <p>时间：${new Date().toLocaleString()}</p>
                <p>环境：${NODE_ENV}</p>
                <p>磁盘路径：${disk.path}</p>
                <p>总容量：${disk.total}</p>
                <p>已用容量：${disk.used}</p>
                <p>空闲容量：${disk.free}</p>
                <p>使用率：${disk.usagePercent}%（阈值：${DISK_THRESHOLD}%）</p>
                <p>风险：磁盘满可能导致日志无法写入、数据无法存储</p>
                <p>解决方案：</p>
                <p>1. 清理无用文件/日志</p>
                <p>2. 扩展磁盘容量</p>
            `;
                ALERT_EMAILS.forEach((email) => {
                    emailTool
                        .sendNotice(email, '[预警] CorpHR磁盘使用率超限告警', alertContent)
                        .catch((mailErr) =>
                            logger.error(`❌ 磁盘告警邮件发送失败：${mailErr.message}`, { metadata: {} }),
                        );
                });
            }
        },
        5 * 60 * 1000,
    );
};

// 停止监控
const stop = () => {
    if (monitorInterval) {
        clearInterval(monitorInterval);
        monitorInterval = null;
        logger.info(`${color.blue}📊  资源监控已停止${color.reset}`, { metadata: {} });
    }
};

module.exports = {
    start,
    stop,
    getMemoryUsage,
    getDiskUsage,
};
